package game.controller;

import game.model.Block;
import game.model.Board;
import game.view.GameView;

/**
 * 控制者，拥有一个Board、一个view、多条MergeRule，能处理多种动作
 *
 * @author 陈渤林
 */
public class Controller {
    /**
     * 被控制的棋盘
     */
    private Board board;
    /**
     * 棋盘的观察者
     */
    private GameView gameView;


    /**
     * 创建方块的规则
     */
    private CreateRule createRule;

    /**
     * 移动方块的规则
     */
    private MoveRule moveRule;
    /**
     * 合并方块的规则
     */
    private MergeRule mergeRule;


    /**
     * 构造时，传入受控制的棋盘、创建规则、移动规则、合并规则，创建相关视图及用户监听器
     *
     * @param board      受控制的棋盘
     * @param moveRule
     * @param createRule
     * @param mergeRule  相关的 MergeRule 列表
     */
    public Controller(Board board, CreateRule createRule, MoveRule moveRule, MergeRule mergeRule) {
        this.board = board;
        this.gameView = new GameView(this.board, new Listener(this));
        this.createRule = createRule;
        this.moveRule = moveRule;
        this.mergeRule = mergeRule;
    }

    /**
     * 关闭窗口
     */
    public void dispose() {
        gameView.dispose();
    }

    /**
     * 初始化游戏
     */
    public void init() {
        for (int x = 0; x < board.getWidth(); ++x) {
            for (int y = 0; y < board.getHeight(); ++y) {
                board.setBlock(x, y, null);
            }
        }
        this.createBlocks();
    }

    /**
     * 创建新的方块
     */
    public boolean createBlocks() {
        if (this.createRule.createBlocks(this.board) == false) return false;
//        this.createRule.createBlocks(this.board);
        this.gameView.update(); // 更新视图
        return true;
    }


    /**
     * 移动方块
     *
     * @param dir 方向类型
     * @return 是否有方块被移动
     */
    public boolean moveBlocks(final Direction dir) {
        boolean ret = this.moveRule.moveBlocks(this.board, dir);
        if (this.mergeRule.mergeBlocks(this.board, dir)) {
            this.moveRule.moveBlocks(this.board, dir);
        }
        this.gameView.update(); // 更新视图
        return ret;
    }

}
